iT邦幫忙

2023 iThome 鐵人賽

DAY 25
1
SideProject30

製作適用於網頁的台灣登山地圖系列 第 25

[Day25] 將等高線塞入向量圖磚

  • 分享至 

  • xImage
  •  

我們在 Day16 有提到過,可以利用 maplibre-contour 這個套件來搭配 Terrain-RGB 圖磚展示等高線。

不過傳統上,等高線的資料來源也是來自向量圖磚服務。因為佔用空間較大,通常不會和平常的地圖物件放在一起,而是屬於獨立的圖磚服務。舉例來說,我們參考的 maptiler-terrain-gl-style 樣式,其等高線資料來源就是商業公司的圖磚服務:

  "sources": {
    ...
    "contours": {
      "type": "vector",
      "url": "https://klokantech.tilehosting.com/data/contours.json?key=xxxxxxxxxxxxxxxxxxxx"
    }

我們之前也提到過,在台灣地區,全球性圖磚服務的高程資料準確度不比內政部的資料準確。因此,我們就如同往常一樣,從資料源頭來產製一下台灣的等高線圖磚服務吧。

取得高程資料

為了魯地圖的每日更新服務,魯地圖團隊的 kcwu 前輩早已將當年度來自內政部的高程資料轉換為 OSM 資料格式。今年度的資料可以在以下網址中取得:

http://moi.kcwu.csie.org/osm_elevations/ele_taiwan_10_100_500-2023.o5m

製作向量圖磚

首先要將高程資料轉換為 tilemaker 可以使用的 PBF 格式,這邊使用 osmconvert 這一命令行工具:

osmconvert --out-pbf ele_taiwan_10_100_500-2023.o5m >contours.pbf

接著,撰寫 tilemaker 使用的設定檔。

{
	"layers": {
		"contour":     { "minzoom":  9, "maxzoom": 14 },
		"contour_z9":  { "minzoom":  9, "maxzoom":  9 , "write_to": "contour" },
		"contour_z10": { "minzoom": 10, "maxzoom": 10 , "write_to": "contour" },
		"contour_z11": { "minzoom": 11, "maxzoom": 11 , "write_to": "contour" },
		"contour_z12": { "minzoom": 12, "maxzoom": 12 , "write_to": "contour" },
		"contour_z13": { "minzoom": 13, "maxzoom": 13 , "write_to": "contour" },
		"contour_z14": { "minzoom": 14, "maxzoom": 14 , "write_to": "contour" }
	},
	"settings": {
		"minzoom":  11,
		"maxzoom":  14,
		"basezoom": 14,
		"include_ids": false,
		"name": "kcwu contour",
		"version": "0.1",
		"description": "Contour from MOI, used for Rudymap",
		"compress": "none"
	}
}

因為在不同縮放層級下,等高線的密集程度應該有別。故我們分別設定了 contour_z9contour_z14 幾個 Tile Layer,並將它們都寫入 contour 這個 Layer。

接著是 Lua 設定檔:

function way_function(way)
    local intervals = {
        z9 =500,
        z10=200,
        z11=100,
        z12=50,
        z13=20,
        z14=10
    }
	local ele = way:Find("ele")

    for zoom, interval in pairs(intervals) do

        if (ele % interval == 0) then 
            way:Layer("contour_" .. zoom, false)
            way:AttributeNumeric("height", ele)

            local index = ele / interval
            if     index % 10 == 0 then way:AttributeNumeric("nth_line", 10)
            elseif index %  5 == 0 then way:AttributeNumeric("nth_line",  5)
            elseif index %  2 == 0 then way:AttributeNumeric("nth_line",  2)
            else                        way:AttributeNumeric("nth_line",  1)
            end
        end
    end

end

分別針對不同的縮放層級,加入對應的等高線間格:

縮放層級 間格
9 500m
10 200m
11 100m
12 50m
13 20m
14 10m

並且為了前端渲染方便,從海拔0m 開始,為每 1,2,5,10 條等高線加入 nth_line 屬性。

那麼下一步,就是使用 tilemaker 來製作圖磚了:

tilemaker --input contours.pbf --output tiles

渲染等高線

其實以上步驟所產生的圖磚,已使用 Github Pages 作成圖磚服務。製圖者可以在 Style 中加入 https://typebrook.github.io/contours/tiles.json 這個用於描述圖磚服務的檔案,來加入新的圖磚來源:

  "sources": {
    "contours": {
      "type": "vector",
      "url": "https://typebrook.github.io/contours/tiles.json"
    }
  },

在 Style 的相關圖層上,可以加入「一般等高線」、「粗等高線」、與「粗等高線的高度文字」等三個圖層,並使用如下的 filter 來過濾每 5、10 條等高線作為「精等高線」:

"filter": [
  "in",
  "nth_line",
  10,
  5
]

渲染的結果如下:
https://ithelp.ithome.com.tw/upload/images/20231010/20162266jkrIGNrTLz.png


上一篇
[Day24] 使用 Sprite 來呈現圖示
系列文
製作適用於網頁的台灣登山地圖25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
jinyar
iT邦新手 5 級 ‧ 2024-03-22 15:31:17

請問內政部提供的高程資料有包含中華民國的所有離島嗎?謝謝!

我要留言

立即登入留言